在 AWS 中,但凡我們開啟的 EC2 Instance,都會自動產生對應的 Metrics。這些 Metrics 可以幫助我們監控 Instance 的即時狀況,還可以與 Auto Scaling Group 配合,進行服務的水平擴展 (HorizontalPodAutoscaler, HPA) 或垂直擴展 (VerticalPodAutoscaler, VPA),這也是如今高適應、高可用部署的基石。
而在 Kubernetes 中,如果想要進行 Pod 擴展 (PodAutoscaler),或使用 kubectl top
指令獲取 CPU 累計使用率、記憶體即時使用率、Pod 資源佔用率等,就必須透過 Metrics Server 取得 Pod 和 Container 的 Metrics。
順便一提,Metrics Server 的前身是 Heapster。由於 Heapster 不夠方便且難以維護,後來提出了 Metrics API 的概念並且推出 Metrics Server 取而代之。
/metrics/resource
和 /stats
Kubelet API 端點訪問資源指標。kubectl top
命令使用。Metrics Server 是 Metrics API 的參考實現。Metrics Server 定時從 Kubelet 的 Summary API (類似 /api/v1/nodes/nodename/stats/summary
) 採集指標資訊,這些聚合過的資料將儲存在記憶體中,且以 Metrics API 的形式暴露出去。
Metrics Server 復用了 API Server 的庫來實現自己的功能,比如鑑權、版本等。為了將資料存放在記憶體中,去掉了默認的 ETCD 儲存,引入了記憶體儲存。由於存放在記憶體中,因此監控資料是沒有持久化的,可以通過第三方儲存來拓展,比如 Prometheus,這與 Heapster 是一致的。
從上述的流程圖和敘述可以看出:
Metrics Server 對叢集和網路組態有特定要求。這些要求不是所有叢集發行版的默認要求。在使用 Metrics Server 之前,請確保叢集發行版滿足以下要求:
hostNetwork
)從 kube-apiserver 訪問--kubelet-insecure-tls
給 Metrics Server 來停用證書驗證)根據官方的指南,使用以下配置進行部署:
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
這時我們應該依然會遇到問題,通常是因為 Kubelet 證書沒有簽名,本篇我們只是操作練習,所以透過傳遞 --kubelet-insecure-tls
參數來關閉驗證。
kubectl patch
指令修改配置kubectl patch -n kube-system deployment metrics-server --type=json \
-p '[{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"--kubelet-insecure-tls"}]'
kubectl top
指令kubectl top nodes
---
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
wslkind-control-plane 109m 0% 795Mi 2%
wslkind-worker 30m 0% 298Mi 0%
wslkind-worker2 28m 0% 403Mi 1%
---------
kubectl top pods -A
---
NAMESPACE NAME CPU(cores) MEMORY(bytes)
ingress-nginx ingress-nginx-controller-666487-phxw4 2m 151Mi
kube-system coredns-7db6d8ff4d-mbgzs 2m 26Mi
kube-system coredns-7db6d8ff4d-z7hhn 2m 24Mi
kube-system etcd-wslkind-control-plane 19m 116Mi
kube-system kindnet-9l97q 1m 20Mi
kube-system kindnet-bn27w 1m 22Mi
kube-system kindnet-x9qmc 1m 20Mi
kube-system kube-apiserver-wslkind-control-plane 37m 214Mi
組態檔案: test-pod.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
app: test-pod
name: test-pod
spec:
containers:
- name: busybox
command:
- /bin/sh
- -c
args:
- "sleep 3600"
image: registry.k8s.io/busybox
kubectl apply -f test-pod.yaml
test-pod
指標資料:kubectl get --raw /apis/metrics.k8s.io/v1beta1/pods | jq '.items[] | select(.metadata.name == "test-pod")'
結果如下
{
"metadata": {
"name": "test-pod",
"namespace": "default",
"creationTimestamp": "2024-07-27T17:47:02Z",
"labels": {
"app": "test-pod"
}
},
"timestamp": "2024-07-27T17:46:52Z",
"window": "13.852s",
"containers": [
{
"name": "busybox",
"usage": {
"cpu": "0",
"memory": "452Ki"
}
}
]
}